/**   
* @Title: JdbcUtil.java 
* @Package com.alibaba.datax.core.util 
* @Description: TODO(用一句话描述该文件做什么) 
* @author cssuger@163.com   
* @date 2016年10月8日 下午4:40:42 
* @version V1.0   
*/
package com.bicon.base.data.common;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * @ClassName: JdbcUtil
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author cssuger@163.com
 * @date 2016年10月8日 下午4:40:42
 * 
 */

public class DbBuilder implements ApplicationContextAware{

	private static DruidDataSource dataSource;
	private static Logger logger = LoggerFactory.getLogger(DbBuilder.class);

	private static final DbBuilder dbbuilder = new DbBuilder();

	private static ApplicationContext context = null;

	public static DataSource getDataSource() {
		if (DbBuilder.dataSource == null) {
			try {
				DbBuilder.dataSource =  context.getBean("dataSource", DruidDataSource.class);
				logger.info("DruidDataSource数据源初始化成功!");
			} catch (Exception ex) {
				logger.info("DruidDataSource数据源初始化失败:" + ex.getMessage());
			}
		}
		return DbBuilder.dataSource;
	}

	public Connection getConnection() {
		try {
			DataSource dataSource = DbBuilder.getDataSource();
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static DbBuilder instance() {
		return dbbuilder;
	}

	public static void close(Connection connection) {
		try {
			DbUtils.close(connection);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public QueryRunner getQueryRunner() {
		return new QueryRunner(DbBuilder.getDataSource());
	}

	private void colseconnection(Connection connection) {
		DbBuilder.close(connection);
			

	}

	/**
	 * 根据sql和对象，查询结果并以对象形式返回
	 * 
	 * @param sql
	 * @param type
	 * @param params
	 * @return
	 */
	public <T> T getBean(String sql, Class<T> type, Object... params) {
		Connection conn = null;
		try {
			QueryRunner runner = getQueryRunner();
			conn = runner.getDataSource().getConnection();
			return (T) runner.query(conn, sql, new BeanHandler<T>(type), params);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			colseconnection(conn);
		}
		return null;
	}

	/**
	 * 根据sql查询list对象
	 * 
	 * @param sql
	 * @param type
	 * @return
	 */
	public <T> List<T> getListBean(Connection connection, String sql, Class<T> type) {
		try {
			QueryRunner runner = new QueryRunner();
			return runner.query(connection, sql, new BeanListHandler<T>(type));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据sql查询map对象的list集合
	 * 
	 * @param sql
	 * @return
	 */
	public static List<Map<String, Object>> getListMap(Connection connection, String sql, Object... params) {
		try {
			QueryRunner runner = new QueryRunner();
			List<Map<String, Object>> mapList = runner.query(connection, sql, new MapListHandler(), params);
			return mapList;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据sql查询list对象
	 * 
	 * @param sql
	 * @param type
	 * @param params
	 * @return
	 */
	public <T> List<T> getListBean(String sql, Class<T> type, Object... params) {
		Connection conn = null;
		try {
			QueryRunner runner = this.getQueryRunner();
			conn = runner.getDataSource().getConnection();
			return runner.query(conn, sql, new BeanListHandler<T>(type), params);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (null != conn) {
				colseconnection(conn);
			}
		}
		return null;
	}

	/**
	 * 保存操作
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public int save(String sql, Object... params) {
		Connection conn = null;
		try {
			QueryRunner runner = getQueryRunner();
			conn = runner.getDataSource().getConnection();
			beginTransaction(conn);
			runner.update(conn, sql, params);
			commit(conn);
			return 1;
		} catch (Exception ex) {
			ex.printStackTrace();
			// logger.error("发生错误,错误原因:{}","主键重复");
			rollback(conn);
		} finally {
			if (null != conn) {
				colseconnection(conn);
			}
		}
		return 0;
	}
	
	/**
	 * 批量保存操作
	 * 
	 * @param sql
	 * @param params,该数组第一个批量次数，第二个是参数个数
	 * @return
	 */
	public int savebacth(String sql, Object[][] params) {
		Connection conn = null;
		try {
			QueryRunner runner = getQueryRunner();
			conn = runner.getDataSource().getConnection();
			beginTransaction(conn);
			runner.batch(conn, sql, params);
			commit(conn);
			return 1;
		} catch (Exception ex) {
			ex.printStackTrace();
			// logger.error("发生错误,错误原因:{}","主键重复");
			rollback(conn);
		} finally {
			if (null != conn) {
				colseconnection(conn);
			}
		}
		return 0;
	}

	/**
	 * Execute an SQL INSERT, UPDATE, or DELETE query.
	 * 
	 * @param sql
	 * @param params
	 * @return The number of rows updated.
	 */
	public int execute(String sql, Object... params) {
		Connection conn = null;
		try {
			QueryRunner runner = getQueryRunner();
			conn = runner.getDataSource().getConnection();
			beginTransaction(conn);
			int r = runner.update(conn, sql, params);
			commit(conn);
			return r;
		} catch (Exception ex) {
			ex.printStackTrace();
			 logger.error("发生错误,错误原因:{}",ex.getMessage());
			rollback(conn);
		} finally {
			if (null != conn) {
				colseconnection(conn);
			}
		}
		return 0;
	}

	/**
	 * 开启事务
	 */
	private void beginTransaction(Connection conn) {
		try {
			// 开启事务
			conn.setAutoCommit(false);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 回滚事务
	 */
	private void rollback(Connection conn) {
		try {
			if (null != conn) {
				conn.rollback();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 提交事务
	 */
	private void commit(Connection conn) {
		try {
			conn.commit();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.context = applicationContext;
		
	}

	 public static void main(String[] args) {
		ApplicationContext  context = new ClassPathXmlApplicationContext(Constants.XMP_PATH);
		DbBuilder dbBuilder =	context.getBean("dbBuilder", DbBuilder.class);
		System.out.println(dbBuilder.getDataSource());
	 }

}
